import type { RouteMeta, RouteComponent } from 'vue-router';
import { constantRoutes, dynamicRoutes } from '@/router/routes'
import { asyncForEachRecursively, mapRecursively } from '@/utils/array-recursion'
import type {Lazy} from '../menu/menu-scan-local'
export interface PageApi {
    url?: string
    antPattern?: string
    method?: string
    pagePath?: string
}

export interface PageView {
    apis: PageApi[]
    path: string
    title?: string
    permission?: string
}


export interface RouteModule {
    module: any
    dynamic: boolean
    meta?: RouteMeta
}


export async function loadPageApiViews(): Promise<PageView[]> {
    const layoutModules = import.meta.glob('@/layout/**/*.vue')
    const viewModules = import.meta.glob('@/views/**/*.vue')
    const modules = {} as typeof viewModules
    for (const key in layoutModules) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        modules[key] = await (layoutModules[key]() as any)
    }
    for (const key in viewModules) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        modules[key] = await (viewModules[key]() as any)
    }

    const routeModules: RouteModule[] = []
    await asyncForEachRecursively(constantRoutes.concat(dynamicRoutes), async (route) => {
        if (!Array.isArray(route.children) || route.children.length == 0) {
            if (typeof route.component == 'function') {
                const routeModule = await new Promise((resolve) => {
                    (route.component as Lazy<RouteComponent>)().then((_component) => {
                        resolve(_component)
                    })
                })

                routeModules.push({
                    module: routeModule,
                    dynamic: true,
                    meta: route.meta
                })
            }else {
                routeModules.push({
                    module: route.component,
                    dynamic: false,
                    meta: route.meta
                })
            }

        }
    })



    return Object.keys(modules).filter((key: string) => {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const module: any = modules[key]
        return typeof module.default.apis == 'object'
    }).map((key: string) => {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const module: any = modules[key]

        const targetRouteModule = routeModules.find(routeModule => {
            return (routeModule.dynamic && module === routeModule.module) || (!routeModule.dynamic && module.default === routeModule.module)
        })

        const apis: PageApi[] = []
        mapRecursively([module.default], (_module) => {
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            const result: Record<string,any> = {}
            const subViews = _module.subViews
            if(subViews) {
                result.children = Object.values(subViews)
            }

            if(_module.apis) {
                apis.push(...Object.keys(_module.apis).map((prop) => {
                    let api = _module.apis[prop];
                    if (typeof api == "function") {
                        try{
                            api = api();
                        }catch(error) {
                            throw {type: 'NoArgsRunApiError', error}
                        }
                    }
                    api.antPattern = api.url.replaceAll("undefined", "*");
                    api.method = api.method || "GET";
                    return api;
                }))
            }
            return result;
        })

        const pageView: PageView = {
            path: key,
            title: targetRouteModule?.meta?.title as string | undefined,
            permission: targetRouteModule?.meta?.permission as string | undefined,
            apis: apis
        }
        pageView.path = key.replace('/src/', '').replace('.vue', '')
        return pageView
    })
}